perm filename MISEDG.SAI[SYS,HE]1 blob sn#004188 filedate 1972-10-24 generic text, type T, neo UTF8
COMMENT ⊗   VALID 00025 PAGES 
RECORD PAGE   DESCRIPTION
 00001 00001
 00007 00002	ENTRY IMAGE,REJSUB,XGETD,INSUB,CURVE
 00012 00003	INTERNAL SAFE REAL ARRAY ITEMVAR MANFRED
 00016 00004		INITIALIZE PROGRAM FOR TV INPUT (TVWID IS LENGTH OF INPUT SQUARE)
 00018 00005		SELECT CORRECT OBJECT BLOCK.  VALUE IS POINTER OR -1 IF NO
 00020 00006		CALL MANFRED'S OPERATOR
 00025 00007		INITIALIZE
 00027 00008		ENTER MAXIMUM DEBUGGING MODE
 00031 00009	⊃ PROCEDURE TO DISPLAY COMPLEXITY OF SCENE AREAS
 00033 00010		DELETE COMMAND - ARG SET TO OBJECT DELETED ON EXIT, NIL IF NONE
 00035 00011	⊃	GIVEN LINE (X1,Y1) , (X2,Y2) TRUNCATE TO FIT ENTIRELY IN TV'S FIELD OF VIEW.
 00037 00012	⊃ COMPACT command - compacts LPS data structure
 00045 00013		RELOOK COMMAND
 00047 00014		FILL DATA ARRAY FROM EDGE DATA RINGS
 00050 00015		INTERIOR EDGE SCANNER ROUTINES
 00052 00016		ANOTHER INTERIOR EDGE SCANNING ROUTINE
 00054 00017		MORE INTERIOR EDGE SCANNING ROUTINES
 00056 00018	⊃  adaptive interior scanner - requires curve fitter running
 00063 00019		NON-ADAPTIVE INTERIOR EDGE SCANNER - CURVE FITTER NOT NEEDED
 00066 00020		CONTINUE
 00068 00021		CONTINUE
 00071 00022		CONTINUE
 00073 00023		CONTINUE
 00076 00024		GUTS OF GET_DATA COMMAND
 00079 00025		FIT COMMAND  STATUS=-1 ON ENTRY IF NO LINE EXTENDING TO BE DONE
 00083 ENDMK
⊗;
ENTRY IMAGE,REJSUB,XGETD,INSUB,CURVE;

BEGIN "MISC"

REQUIRE "PREAMB.SAI[SYS,HE]" SOURCE_FILE;
REQUIRE "DPYSUB.HDR[SYS,HE]" SOURCE_FILE;
REQUIRE "SQRT[SYS,HE]" LOAD_MODULE;
REQUIRE 500 STRING_SPACE;

EXTERNAL PROCEDURE SCANINIT;
EXTERNAL PROCEDURE CWHEEL(INTEGER C);
EXTERNAL INTEGER PROCEDURE GIOWD(INTEGER ARRAY A);
EXTERNAL BOOLEAN PROCEDURE EJLI(INTEGER X, Y, ANGLE, FLAG);
EXTERNAL PROCEDURE FORG.;
EXTERNAL INTEGER PROCEDURE GGETD(INTEGER PNTR, CNT; REFERENCE BOOLEAN ERROR);
EXTERNAL BOOLEAN PROCEDURE GIFTIE(INTEGER PNTR, FLD; REFERENCE BOOLEAN ERROR);
EXTERNAL PROCEDURE GDOWN(REFERENCE INTEGER PNTR, FLD; REFERENCE BOOLEAN ERROR);
EXTERNAL PROCEDURE GFORWR(REFERENCE INTEGER PNTR, FLD; REFERENCE BOOLEAN ERROR);
EXTERNAL PROCEDURE GBACK(REFERENCE INTEGER PNTR, FLD; REFERENCE BOOLEAN ERROR);
EXTERNAL INTEGER PROCEDURE GKILBL(REFERENCE INTEGER PNTR; REFERENCE BOOLEAN FLAG);
EXTERNAL INTEGER PROCEDURE GETCOR(INTEGER SIZE);
EXTERNAL PROCEDURE RELCOR(INTEGER PNTR);
EXTERNAL BOOLEAN PROCEDURE GSTATZ(INTEGER MASK, PNTR; REFERENCE BOOLEAN ERR);
EXTERNAL BOOLEAN PROCEDURE GSETST(INTEGER MASK, PNTR; REFERENCE BOOLEAN ERR);
EXTERNAL BOOLEAN PROCEDURE GSTATO(INTEGER MASK,PNTR; REFERENCE BOOLEAN ERR);
EXTERNAL PROCEDURE GRSETS(INTEGER MASK,PNTR; REFERENCE BOOLEAN ERR);
EXTERNAL INTEGER PROCEDURE GCOUNT(INTEGER PNTR, FLD; REFERENCE BOOLEAN ERR);
EXTERNAL PROCEDURE PICINI(INTEGER CHAN,FILE,EXT,PPN;REFERENCE BOOLEAN FAIL;INTEGER ARRAY STOR);
EXTERNAL PROCEDURE PICRD(REFERENCE BOOLEAN FAIL; INTEGER ARRAY STOR);
EXTERNAL PROCEDURE PICWR(INTEGER CHAN,FILE,EXT,PPN;REFERENCE BOOLEAN FAIL;INTEGER ARRAY STOR);
EXTERNAL PROCEDURE TRACCHK;
EXTERNAL BOOLEAN PROCEDURE EDGE_KKP(REFERENCE ITEMVAR ARG; REFERENCE INTEGER STATUS);
EXTERNAL INTEGER PROCEDURE GCREBL(INTEGER TYPE; REFERENCE BOOLEAN ERR);
EXTERNAL PROCEDURE GSTORD(INTEGER VAL,PNTR,CNT;REFERENCE BOOLEAN ERR);
EXTERNAL PROCEDURE GLINKR(INTEGER PNTRA,FLDA,PNTR,FLD;REFERENCE BOOLEAN ERR);
EXTERNAL PROCEDURE GCRERI(INTEGER PNTRA,FLDA,PNTR,FLD;REFERENCE BOOLEAN ERR);
EXTERNAL PROCEDURE GULINK(INTEGER PNTR,FLD;REFERENCE BOOLEAN FLAG);
FORTRAN PROCEDURE DATGET;
FORTRAN PROCEDURE DATPUT;
EXTERNAL INTEGER PROCEDURE SETANG(INTEGER X,Y);
EXTERNAL PROCEDURE OUTOBJ(REFERENCE INTEGER STATUS);
EXTERNAL PROCEDURE SEENLINK(INTEGER ARG,BOX);
EXTERNAL REAL PROCEDURE SQRT(REAL X);
EXTERNAL PROCEDURE FADCHG(REAL X,Y;PROCEDURE FOO);
EXTERNAL PROCEDURE FRDCHG(REAL X,Y;PROCEDURE FOO);
EXTERNAL PROCEDURE CLIPCHG(INTEGER CLIP);
EXTERNAL INTEGER PROCEDURE GENTER(INTEGER X,Y; REFERENCE BOOLEAN TEST,DIR);
EXTERNAL PROCEDURE TVIN;
EXTERNAL PROCEDURE EJINIT;
EXTERNAL BOOLEAN PROCEDURE PLTPNT(INTEGER OBJLST; REFERENCE INTEGER BUF);
FORWARD SIMPLE PROCEDURE OUTMAN;
FORWARD INTERNAL PROCEDURE CURVE(REFERENCE ITEMVAR ARG; REFERENCE INTEGER STATUS);
INTERNAL SAFE REAL ARRAY ITEMVAR MANFRED;
SAFE REAL ARRAY ITEMVAR NEWCAM, OUTXY, INXY, RAI;
DEFINE DEBOUT(A)="IF TYP_EDGE THEN OUTSTR(A&CRLF)",
	CRLF="'15&'12",
	SAFEX="", GET(I)="FOOLX(GGETD(PNTR,I,FLAG))", STLEN="6", DSK="5", ⊃="COMMENT",
	D1MAX="1000", D2MAX="100", MANMAX="100",
	DEL(A)="FOREACH RAI|GLOBAL A≡RAI DO BEGIN;GLOBAL ERASE A≡RAI;GLOBAL DELETE(RAI);END",
	OUTLIN="2",CORRNG="1", DISFRM="2", PNTNUM="1", OBJNUM="3",OBJPNT="1",
	CORPNT="1", SEGPNT="1", OBJRNG="1", LIMIT="4", CAMERA="8";
SAFEX INTERNAL INTEGER ARRAY STACK, COSTKX, COSTKY[1:STLEN];
INTERNAL SAFEX INTEGER ARRAY DISPL1[1:D1MAX+5],DISPL2[1:D2MAX+5];
INTERNAL INTEGER DISPNT, BACKFL, MANFCNT;
INTERNAL REAL OWID, RADSQ, RADHLF, DIFFX, ORX, ORY, OCL, OSL, OD, OB;
REAL OGRAD, X;
INTERNAL BOOLEAN DISFLG, DEBUGX, ACCOMINIT;
BOOLEAN FLAG, GUNON, MAXDEB, DO_COL;
INTEGER FLD, FRAM, I, N, PNTR, PPN, SIZE, TEMP, TEST, BOXINC, TMCNT, FRAMX;
EXTERNAL INTEGER XSTRT, YSTRT, TVWORD, TMAX, BMAX, RSMAX, LSMAX, BITS, OPSIZE, TOPLST,
	OBJLST, PNTLST, GPNTR, TEMPNT, LSIDE, RSIDE, FLINE, LLINE, BCLIP, TCLIP, SAITEM,
	DEFT, DEFB, DEFR, DEFLX, TVWID, SEGLST, CORLST, CURTEM,DISTST,DEBFRM;
EXTERNAL REAL COH,SIDLEN, CONF, CIRCLE;
EXTERNAL BOOLEAN STVFL, ST, STV, TRAC, SLIM,SCAN_ACC, EDGINIT, DEBDEL;

SAFEX INTEGER ARRAY BOXTAB[1:20];
REAL PROCEDURE DIN(INTEGER I,J); RETURN(GLOBAL DATUM(INXY)[I,J]);
REAL PROCEDURE DOUT(INTEGER I,J); RETURN(GLOBAL DATUM(OUTXY)[I,J]);

comment		variables:
OUTXY,INXY	arrays of corner coordinates. OUTXY will have a closed outlin, if any.
		INXY will have line segments, if any.
STACK,COSTKX,COSTKY are stacks containing the last STLEN coordinates seen by the edge
		follower and the pointers to the data structure entry.
DISPNT		contains the current display frame number.
OBJCNT		contains the object number.
DISFLG		is TRUE if display has been suppressed for any reason.
ACCOMINIT	is TRUE if accomodation routines are initialized.
CIRCLE		is the radius of the Manfred operators
DO_COL		is TRUE if filters to be changed during inside scaning;

SIMPLE INTERNAL PROCEDURE DPYPNT(INTEGER X,Y);
	BEGIN EXTERNAL INTEGER DEBFRM;
	INTEGER DSAVE;
	DSAVE ← DPYPARS;
	DPYSET(DISPL2);
	APOINT(X*3-512,512-Y*3);
	DPYOUT(DEBFRM);
	DPYRESET(DSAVE);
	END;
COMMENT		INITIALIZE PROGRAM FOR TV INPUT (TVWID IS LENGTH OF INPUT SQUARE);

SIMPLE INTERNAL PROCEDURE INITTV;
	BEGIN
	RELCOR(TVWORD);
	SIZE ← (TVWID/9+2)*(TVWID+1);
	IF SIZE<500 THEN SIZE ← 500;
	STV ← STVFL ← ST ← FALSE;
	TVWORD ← GETCOR(SIZE);
	BACKFL ← 0;
	DEFR ← 325;
	DEFLX ← 10;
	DEFT ← 15;
	DEFB ← 250;
	XSTRT ← YSTRT ← 0;
	EDGINIT ← ACCOMINIT ← FALSE;
	CHANGE_ACC ← TRUE;
	END;

COMMENT		INITIALIZE PROGRAM FOR DISK FILE NAM.DAT;

INTERNAL BOOLEAN PROCEDURE INITDK(STRING NAM);
	BEGIN INTEGER I, FAIL;
	INTEGER ARRAY STOR[1:25];
	LABEL L1;
	RELCOR(TVWORD);
	TVWORD ← 0;
	STV ← STVFL ← ST ← TRUE;
	N ← CVFIL(NAM,I,PPN);
	I ← GETCHAN;
	PICINI(I,N,CVSIX("DAT"),PPN,FAIL,STOR);
	IF FAIL∨¬STOR[1] THEN
L1:		BEGIN INITTV; RELEASE(I); RETURN(FALSE); END;
	TVWORD ← GETCOR(STOR[1]);
	BACKFL ← 0;
	STOR[2] ← 0;
	ARRBLT(STOR[3],STOR[2],23);
	STOR[1] ← (TVWORD LAND '777777)+1;
	PICRD(FAIL,STOR);
	IF FAIL THEN GO TO L1 ELSE RELEASE(I);
	RSMAX ← DEFR ← RSIDE;
	LSMAX ← DEFLX ← LSIDE;
	TMAX ← DEFT ← FLINE;
	BMAX ← DEFB ← LLINE;
	BCLIP ← 7;
	TCLIP ← 0;
	XSTRT ← YSTRT ← 0;
	ACCOMINIT ← TRUE;
	EDGINIT ← CHANGE_ACC ← FALSE;
	RETURN(TRUE);
	END;
COMMENT		SELECT CORRECT OBJECT BLOCK.  VALUE IS POINTER OR -1 IF NO
		BLOCK.  EXECUTE XEQ IF FLG IS TRUE;

SIMPLE INTERNAL INTEGER PROCEDURE GETOBJ(REFERENCE ITEMVAR ARG; BOOLEAN FLG; REFERENCE BOOLEAN PROCEDURE XEQ);
	BEGIN
	LABEL L1;
	IF ¬GIFTIE(PNTR←TOPLST,FLD←OBJPNT,FLAG)∨FLAG THEN RETURN(-1);
	GDOWN(PNTR,FLD,FLAG);
	TEST ← PNTR;
L1:	IF ARG≠EVERY THEN
		BEGIN
		IF GGETD(PNTR,OBJNUM,FLAG)= CVN(ARG) THEN
			RETURN(IF FLG∧¬XEQ(PNTR,ARG) THEN -1 ELSE PNTR)
		END ELSE IF ¬FLG∨XEQ(PNTR,ARG) THEN
			BEGIN
			ARG ← CVI(GGETD(PNTR,OBJNUM,FLAG));
			RETURN(PNTR);
			END;
	GFORWR(PNTR,FLD,FLAG);
	IF PNTR≠TEST THEN GO TO L1;
	RETURN(-1);
	END;

COMMENT		DUMMY ROUTINE FOR GETOBJ;

SIMPLE BOOLEAN PROCEDURE DUMMY(INTEGER A; ITEMVAR B);
	RETURN(FALSE);

COMMENT		STORE OUTPUT OF OPERATOR IF INSIDE WAS CALLED;

SIMPLE INTERNAL PROCEDURE MANUPD;
	BEGIN
	DEFINE D(A)="GLOBAL DATUM(MANFRED)[MANFCNT,A]";
	IF MANFRED≠NIL THEN
		BEGIN
		IF MANFCNT>MANMAX THEN OUTMAN;
		IF ORX<10.0∨ORY<10.0 THEN OUTSTR("X,Y OUT OF BOUNDS - MANFCNT ="&CVS(MANFCNT)&CRLF);
		D(1) ← ORX; D(2) ← ORY;
		D(3) ← OCL; D(4) ← OSL;
		D(5) ← OD; D(6) ← OB;
		MANFCNT ← MANFCNT + 1;
		END;
	END;
COMMENT		CALL MANFRED'S OPERATOR;

COMMENT		RETURNS:
		-1	OUTSIDE FIELD OF VIEW
		0	NOTHING SEEN
		1	NOISY EDGE - JUMP AHEAD
		2	FUNNY BRIGHNESS
		3	OK;

INTERNAL INTEGER PROCEDURE YOPER(INTEGER X, Y; REFERENCE INTEGER ANGLE;INTEGER CW; BOOLEAN TRAC,FLAG);
	BEGIN REAL RAD, TH;
	EXTERNAL REAL B, TM ,TP, OPX, OPY, CX, CY, LINWID;
	EXTERNAL BOOLEAN WEAK, NOISY, NEARED, OPOOB, BCOMP, ISLINE, ISEDGE;
	BOOLEAN VAL;
	INTEGER I, RET, XX, YY;

	PROCEDURE DISP(STRING LAB; INTEGER X, Y);
		BEGIN EXTERNAL REAL COH, OPXM, OPYM, OPXP, OPYP;
		DEFINE OBOOL(X)="(""  X ="")&(IF X THEN ""TRUE"" ELSE ""FALSE"")";
		SAFE INTEGER ARRAY D[1:200];
		STRING FOO;
		INTEGER DPY, I, J;
		GETFORMAT(I, J);
		SETFORMAT(7,3);
		IF DEBDEL THEN
			BEGIN
			DPY ← DPYPARS;
			IF ¬MAXDEB THEN FRAMX ← GETPOG;
			DPYSET(D);
			DPYBRT(7);
			FADCHG(0,0,AIVECT);
			END;
		FOO ← CRLF&"	"&LAB&OBOOL(VAL)&CRLF&
			"X,Y="&CVS(X)&","&CVS(Y)&"    "&CVOS(X)&CVOS(Y)&CRLF&
			"X,Y (P M)="&CVF(OPXP)&","&CVF(OPYP)&"   "&CVF(OPX)&","&
			CVF(OPY)&"   "&CVF(OPXM)&","&CVF(OPYM)&CRLF&
			"DIR. VECTOR="&CVF(CX)&","&CVF(CY)&CRLF&
			"B, TM, TP="&CVF(B)&"   "&CVF(TM)&"   "&CVF(TP)&CRLF&
			"COH, LINWID="&CVF(COH)&"   "&CVF(LINWID)&CRLF&
			OBOOL(WEAK)&OBOOL(NOISY)&OBOOL(NEARED)&OBOOL(BCOMP)&CRLF&
			OBOOL(OPOOB)&OBOOL(ISLINE)&OBOOL(ISEDGE)&CRLF;
		IF ¬MAXDEB THEN OUT(14,FOO);
		IF DEBDEL THEN
			BEGIN
			DPYSST(FOO);
			IF MAXDEB THEN
				BEGIN
				DPYBIG(4);
				AIVECT(-300,-500);
				DPYSST("DMODE: Accom, Exit, Video, Trace");
				END;
			DPYOUT(FRAMX);
			IF ¬MAXDEB THEN
				BEGIN
				OUT(14,INCHWL&CRLF);
				RELPOG(FRAMX);
				END;
			DPYRESET(DPY);
			END;
		SETFORMAT(I,J);
		RETURN;
		END;

	OGRAD ← OWID ← -1.0;
	VAL ← EJLI(X,Y,ANGLE,FLAG);
	IF DEBUGX THEN DISP("FIRST", X, Y);
	IF OPOOB THEN RETURN(-1);
	IF VAL∧(NEARED∨BCOMP)∧((XX←ORX)≠X∨(YY←ORY))≠Y THEN
		BEGIN
		VAL ← EJLI(OPX+.5,OPY+.5,ANGLE,FLAG);
		IF DEBUGX THEN DISP("SECOND", OPX+.5, OPY+.5);
		IF OPOOB THEN RETURN(-1);
		END;
	OB ← B;
	OD ← TM MAX (TM+TP);
	IF VAL THEN
		BEGIN
		ORX ← OPX;
		ORY ← OPY;
		IF ¬BCOMP THEN BEGIN OCL ← CX;OSL ← CY;END;
		ANGLE ← SETANG(OCL*15.0,OSL*15.0);
		RET ← 3;
		END ELSE IF NOISY THEN RET←1 ELSE RET←0;
	IF DEBUGX THEN DPYPNT(X,Y);
	IF OB=0∧OD=0 THEN
		BEGIN
		IF RET=3 THEN RET←2;
		OB ← OD ←GENTER(X,Y,I←0,I);
		END ELSE
	IF RET≥0 THEN IF CW>0 THEN OD←OB+OD ELSE BEGIN OB↔OD;OB←OB+OD;END;
	IF TRAC∧RET≥2 THEN MANUPD;
	RETURN(RET);
	END;
COMMENT		INITIALIZE;

EXTERNAL PROCEDURE REGEN(INTEGER OBJLST);

SIMPLE INTERNAL PROCEDURE DISINT;
	BEGIN INTEGER I;
	IF ¬RUN THEN DPYTYP(-140,15,1);
	DISTST ← 15;
	DISFLG ← FALSE;
	DPYSET(DISPL1);
	DPYBRT(7);
	DPYBIG(4);
	GPNTR ← GIOWD(STACK);
	OVERLAY ← TRUE;
	MANFRED ← NIL;
	IF DISDEV THEN RETURN;
	I ← -1;
	START_CODE DEFINE TTY="'51000000000";
	TTY 6,I;
	END;
	DISDEV←IF I<0 THEN 2 ELSE IF I LAND '20000000 THEN 3 ELSE 1;
	END;

COMMENT		FOOL INTEGER → REAL  TYPE CONVERSION CHECK;

SIMPLE INTERNAL REAL PROCEDURE FOOLX(INTEGER A);
	BEGIN REAL C;START_CODE DEFINE MOVE="'200000000000";MOVE A;MOVEM C;END;
	RETURN(C);
	END;

SIMPLE PROCEDURE DISREL(INTEGER PNTR);
	BEGIN
	DISPNT ← GGETD(PNTR,DISFRM, FLAG);
	IF DISPNT<0 THEN RETURN;
	RELPOG(DISPNT);
	REGEN(-1);
	GSTORD(-1,PNTR,DISFRM,FLAG);
	END;

SIMPLE INTERNAL PROCEDURE COLON;
	DO_COL ← TRUE;

SIMPLE INTERNAL PROCEDURE COLOFF;
	DO_COL ← FALSE;
COMMENT		ENTER MAXIMUM DEBUGGING MODE;

INTERNAL PROCEDURE DMODE;
	BEGIN REAL RAD;
	LABEL OUTLAB;
	INTEGER I, J, ANG, S, PNTR, TSAV, BSAV, LSAV, RSAV, PSAV;
	EXTERNAL REAL ORX, ORY,TOLTRA;
	EXTERNAL PROCEDURE INP;
	EXTERNAL PROCEDURE EDGEON;
	EXTERNAL INTEGER PROCEDURE SEEN(REAL X,Y,INC; REFERENCE INTEGER PNTR);
	EXTERNAL PROCEDURE TRACE(INTEGER X,Y; REFERENCE ITEMVAR ARG;REFERENCE INTEGER STAT);
	EXTERNAL PROCEDURE VIDEO(INTEGER EXP, X, Y);
	EXTERNAL BOOLEAN PROCEDURE ACCOMO(INTEGER X,Y; REFERENCE INTEGER ANG,CW);
	IF DISDEV≠2 THEN BEGIN OUTSTR("NO DEBUGGING ON THIS DEVICE"&CRLF);RETURN;END;
	PSAV ← DPYPARS;
	MAXDEB ← TRUE;
	INP;
	TSAV ← FLINE;
	BSAV ← LLINE;
	LSAV ← LSIDE;
	RSAV ← RSIDE;
	ANG ← 0;
	FRAMX ← GETPOG;
	IF DEBUGX∧DEBFRM≥0 THEN RELPOG(DEBFRM);
	IF (DEBFRM←GETPOG)≥0 THEN DEBUGX ← TRUE ELSE OUTSTR("NO FREE FRAMES"&CRLF);
	RAD ← CIRCLE/2;
	DEBDEL ← TRUE;
	FOR I←BSAV STEP -RAD UNTIL TSAV DO FOR J←LSAV STEP RAD UNTIL RSAV DO
		BEGIN INTEGER ANS, STAT;
		ITEMVAR FOO;
		LABEL L;
		OUTSTR("YOPER="&CVS(STAT ← YOPER(J,I,ANG,0,FALSE,0))&CRLF);
		IF STAT>0 THEN OUTSTR("SEEN="&CVOS(SEEN(ORX,ORY,TOLTRA,PNTR))&"  PNTR="&CVOS(PNTR)&CRLF);
L:		ANS ← INCHWL;
		IF ANS="Y" THEN GO TO OUTLAB;
		IF ANS="T" THEN
			BEGIN
			DEBUGX ← DEBDEL ← MAXDEB ← FALSE;
			RELPOG(FRAMX);
			DPYRESET(PSAV);
			TRACE(ORX+.5,ORY+.5,FOO,STAT);
			PSAV ← DPYPARS;
			OUTOBJ(STAT);
			DEBUGX ← DEBDEL ← MAXDEB ← TRUE;
			FRAMX ← GETPOG;
			END;
		IF ANS="V" THEN
			BEGIN
			FLINE ← TSAV;
			LLINE ← BSAV;
			LSIDE ← LSAV;
			RSIDE ← RSAV;
			TVIN;
			VIDEO(2,LSIDE,FLINE);
			GO TO L;
			END;
		IF ANS="A" THEN
			BEGIN
			OUTSTR("ACCOM="&CVS(ACCOMO(ORX+.5,ORY+.5,ANG,STAT←0))&CRLF);
			GO TO L;
			END;
		IF ANS="D" THEN
			BEGIN "DSKOUT"
			STRING NAM;
			INTEGER I, N, FAIL;
			INTEGER ARRAY STOR[1:25];
			OUTSTR("FILE="&CRLF);
			NAM ← INCHWL;
			N ← CVFIL(NAM,I,PPN);
			I ← GETCHAN;
			STOR[2] ← 0;
			ARRBLT(STOR[3],STOR[2],23);
			STOR[1] ← TVWORD+1;
			PICWR(I,N,CVSIX("DAT"),0,FAIL,STOR);
			RELEASE(I);
			END "DSKOUT";
		END;
OUTLAB:	DEBUGX ← DEBDEL ← MAXDEB←FALSE;
	DPYRESET(PSAV);
	RELPOG(FRAMX);
	RELPOG(DEBFRM);
	RETURN;
	END;
⊃ PROCEDURE TO DISPLAY COMPLEXITY OF SCENE AREAS;

INTERNAL PROCEDURE PTSHOW;
	BEGIN SAFE INTEGER ARRAY BUF[1:1000];
	EXTERNAL INTEGER PTSEEN, PTLENG;
	EXTERNAL INTEGER PROCEDURE GLABEL(REFERENCE INTEGER A);
	INTEGER FRAM, PT,J, K, L, M, PSAV;
	DEFINE SQ="32",XS="((333/SQ)+1)",YS="(256/SQ)",SQH="SQ/2";
	PSAV ← DPYPARS;
	FRAM ← GETPOG;
	DPYSET(BUF); DPYBIG(2); DPYBRT(7);
	PT ← GLABEL(PTSEEN);
	FOR I← XS-1 STEP -1 UNTIL 1 DO
		BEGIN FADCHG(I*SQ,0,AIVECT);FADCHG(I*SQ,256,AVECT);END;
	FOR I← YS-1 STEP -1 UNTIL 1 DO
		BEGIN FADCHG(0,I*SQ,AIVECT);FADCHG(333,I*SQ,AVECT);END;
	SETFORMAT(0,0);
	FOR I←0 STEP 1 UNTIL PTLENG-1 DO
		BEGIN "A"
			START_CODE
			MOVE 1,@PT;
			MOVEM 1,SAITEM;
			END;
		PT ← PT+1;
		IF SAITEM>0 THEN
			BEGIN "C"
			FADCHG((I MOD XS)*SQ+3,(I DIV XS)*SQ+SQH+5,AIVECT);
			M ← GCOUNT(SAITEM,1,FLAG);
			DPYSST(CVS(M));
			IF M>0 THEN
				BEGIN "B"
				K ← 0;
				GDOWN(SAITEM,L←1,FLAG);
				FOR J←1 STEP 1 UNTIL M DO
					BEGIN K←K+GCOUNT(SAITEM,1,FLAG);GFORWR(SAITEM,L,FLAG);END;
				DPYSST("/"&CVS(K));
				END "B";
			END "C";
		END "A";
	DPYOUT(FRAM);
	INCHWL;
	RELPOG(FRAM);
	DPYRESET(PSAV);
	REGEN(-1);
	END;
COMMENT		DELETE COMMAND - ARG SET TO OBJECT DELETED ON EXIT, NIL IF NONE
		STATUS=-1 IF NO OBJECT;

INTERNAL PROCEDURE REJSUB(REFERENCE ITEMVAR ARG; REFERENCE INTEGER  STATUS);
	BEGIN SET FOO;
	SAFEX REAL ARRAY ITEMVAR RAI;
	STATUS ← 0;
	IF (PNTR←GETOBJ(ARG,FALSE,DUMMY))<0 THEN
		BEGIN
		STATUS ← -1;
		ARG ← NIL;
		RETURN;
		END;
	DISREL(PNTR);
	OBJLST ← PNTR;
	FORG.;
	TEMP ← PNTR;
	GBACK(PNTR,FLD←OBJRNG,FLAG);
	OBJLST ← PNTR;
	FOO ← (GLOBAL BOUNDARY⊗ARG)∪(GLOBAL INSIDE_EDGES⊗ARG);
	GLOBAL ERASE ANY⊗ARG≡ANY;
	FOREACH RAI|RAI IN FOO DO GLOBAL DELETE(RAI);
	RAI ← CVI(GGETD(TEMP,CAMERA,FLAG));
	IF RAI≠NIL THEN GLOBAL DELETE (RAI);
	GKILBL(TEMP,FLAG);
	SEGLST ← TEMPNT ← PNTLST ← -1;
	FOR I ← 1 STEP 1 UNTIL STLEN DO STACK[I] ← COSTKX[I] ← COSTKY[I] ← -1;
	END;
⊃	GIVEN LINE (X1,Y1) , (X2,Y2) TRUNCATE TO FIT ENTIRELY IN TV'S FIELD OF VIEW.
		RETURN FALSE IF ENTIRE LINE OUTSIDE;

BOOLEAN PROCEDURE INTEST(REFERENCE REAL X1,Y1,X2,Y2);
	BEGIN REAL A,B,C;
	INTEGER IND;
	SAFEX REAL ARRAY COORDS[1:2,1:2];

	SIMPLE BOOLEAN PROCEDURE SETUP(REAL VAL,OTH,F1,F2;INTEGER I1,I2);
		BEGIN
		IF F1≤VAL≤F2∨F2≤VAL≤F1 THEN
			BEGIN
			COORDS[IND←IND+1,I1] ← VAL;
			COORDS[IND,I2] ← OTH;
			IF IND=2 THEN RETURN(TRUE);
			END;
		RETURN(FALSE);
		END;

	IF 0.0<X1<333.0∧0.0<X2<333.0∧0.0<Y1<256.0∧0.0<Y2<256.0 THEN RETURN(TRUE);
	A ← Y2-Y1;	B ← X1-X2;	C ← X2*Y1-X1*Y2;
	IND ← 0;
	IF (A≠0)∧(((Y1≤0.0≤Y2∨Y2≤0.0≤Y1)∧SETUP(C/A,0.0,X1,X2,1,2))∨
		((Y1≤256.0≤Y2∨Y2≤256.0≤Y1)∧SETUP((C-256.0*B)/A,256.0,X1,X2,1,2)))∨
	   (B≠0)∧(((X1≤0.0≤X2∨X2≤0.0≤X1)∧SETUP(C/B,0.0,Y1,Y2,2,1))∨
		((X1≤333.0≤X2∨X2≤333.0≤X1)∧SETUP((C-333.0*A)/B,333.0,Y1,Y2,2,1))) THEN;
	IF ¬IND THEN RETURN(FALSE);
	IF ¬(0.0<X1<333.0)∨¬(0.0<Y1<256.0) THEN
		BEGIN
		X1 ← COORDS[IND,1];
		Y1 ← COORDS[IND,2];
		IND ← IND-1;
		END;
	IF ¬(0.0<X2<333.0)∨¬(0.0<Y2<256.0) THEN
		BEGIN
		IF ¬IND THEN RETURN(FALSE);
		X2 ← COORDS[IND,1];
		Y2 ← COORDS[IND,2];
		END;
	RETURN(TRUE);
	END;
⊃ COMPACT command - compacts LPS data structure
	uses EDGES⊗ARG≡foo or BOUNDARY⊗ARG≡foo as available

		-2	no outline
		-1	no object
		0 	ok - used EDGES association
		1 	ok - used BOUNDARY association
;

	⊃	fill boxtab with box numbers in grid which contain a point
		less than EPSILON from the line Ax+By+C=0 given endpoints
		(X1,Y1) and (X2,Y2);

SIMPLE PROCEDURE GET_BOX(REAL X1, Y1, X2, Y2);
	BEGIN INTEGER INCR, BOX, TBOX;
	REAL HROW, ROW, COL, T1, A, B, C, D, START, DT, XX1, XX2;
	LABEL L1, L2, L3, L4, L5, FINI;
	DEFINE LEN="32.0",  HLEN="LEN/2.0", EPSILON="4",HEPS="HLEN+EPSILON",WID="11.314",
		COORD(X)="(X DIV LEN)*LEN+HLEN";
⊃ LEN, HLEN, AND HEPS ARE FUNCTIONS OF THE GRID SIZE SET IN SEEN.FAI, WID←SQRT(2*HLEN↑2);

	BOXINC ← 0;
	XX1 ← X1;
	XX2 ← X2;
	IF XX1>XX2 THEN XX1↔XX2;
	IF Y1>Y2 THEN BEGIN X1↔X2; Y1↔Y2; END;
	IF (ROW←COORD(Y1)-LEN)<0 THEN ROW ← HLEN;
	HROW ← COORD(Y2);
	COL ← COORD(X1);
	A ← Y2-Y1;		⊃ compute line equation;
	B ← X1-X2;
	C ← X2*Y1-X1*Y2;
	D ← SQRT(A↑2+B↑2);
L1:	INCR ← 0;		⊃  loop for each row of grid;
	START ← COL;

	TBOX ← BOX ← (ROW DIV LEN)*(333 DIV LEN)+COL DIV LEN;
L3:	IF XX1≥COL+HEPS∨XX2≤COL-HEPS∨Y1≥ROW+HEPS∨Y2≤ROW-HEPS THEN GO TO L2;
	DT ← ABS((A*COL+B*ROW+C)/D);	⊃ loop for each box in row;
	IF DT-EPSILON>WID THEN GO TO L2;	⊃ box center (COL,ROW) too far from line;
	IF DT-EPSILON≤HLEN THEN GO TO L4;	⊃ line inside box;

⊃	check for intersection of line and top or bottom of box +- EPSILON;

	IF ABS(A)<0.00005 THEN IF ROW-HEPS≤Y1≤ROW+HEPS THEN GO TO L4 ELSE GO TO L2;
	T1 ← (-B*(ROW-HEPS)-C)/A;
	IF COL-HEPS≤T1≤COL+HEPS∧XX1-HEPS≤T1≤XX2+HEPS THEN GO TO L4;
	T1 ← (-B*(ROW+HEPS)-C)/A;
	IF COL-HEPS≤T1≤COL+HEPS∧XX1-HEPS≤T1≤XX2+HEPS THEN GO TO L4;
⊃	Not inside box. If INCR=0 or 1 then done with row, else go right;

L2:	IF INCR=-1 THEN BEGIN INCR←1; COL ← START; BOX←TBOX; GO TO L5; END;
	ROW ← ROW+LEN;
	IF ROW<HROW THEN COL←COORD("(-B*ROW-C)/A") ELSE
		IF ROW-LEN=HROW∨ROW=HROW THEN COL←COORD(X2) ELSE GO TO FINI;
	GO TO L1;

⊃	Box near line, store number and continue;

L4:	BOXTAB[BOXINC←BOXINC+1] ← BOX;
	IF ¬INCR THEN INCR ← -1;
L5:	IF ¬(0<(COL←COL+INCR*LEN)<333) THEN GO TO L2;
	BOX ← BOX+INCR;
	GO TO L3;

⊃	Done, create a LINE block and fill it;

FINI:	SAITEM ← GCREBL(CVSIX("LINE"),FLAG);
	DATPUT(SAITEM,1,8,A,B,C,X1,Y1,X2,Y2,D);
	IF GIFTIE(OBJLST,CORPNT,FLAG) THEN GLINKR(CORLST,CORRNG,SAITEM,CORRNG,FLAG) ELSE
		GCRERI(OBJLST,CORPNT,SAITEM,CORRNG,FLAG);
	CORLST ← SAITEM;
	END;

INTERNAL PROCEDURE COMP(REFERENCE ITEMVAR ARG; REFERENCE INTEGER STATUS);
	BEGIN
	INTEGER I, N, J;
	REAL T, B, L, R, X, Y, XX, YY;
	BOOLEAN SIMPLINES, FLAG;
	SET FOO;
	ITEMVAR OLDARG;

	SIMPLE BOOLEAN PROCEDURE CTEST(REFERENCE INTEGER P;REFERENCE ITEMVAR ARG);
		RETURN(GSTATZ(16,P,FLAG));
	
	T ← L ← 500.0;
	R ← B ← 0;
	OLDARG ← ARG;
	IF ARG≠EVERY∧(TEMPNT←GETOBJ(ARG,FALSE,DUMMY))<0 THEN
		BEGIN
		OLDARG ← NIL;
		TEMPNT ← GCREBL(CVSIX("OBJECT"),FLAG);
		IF GIFTIE(TOPLST,OBJPNT,FLAG) THEN GLINKR(OBJLST,OBJRNG,TEMPNT,OBJRNG,FLAG) ELSE
			GCRERI(TOPLST,OBJPNT,TEMPNT,OBJRNG,FLAG);
		OBJLST ← TEMPNT;
		GSTORD(-1,OBJLST,DISFRM,FLAG);
		GSTORD(CVN(ARG),OBJLST,OBJNUM,FLAG);
		GSTORD(IF CVN(CURCAM)>0 THEN CVN(CURCAM) ELSE CVN(NIL),OBJLST,CAMERA,FLAG);
		GSETST(73,OBJLST,FLAG);
		END ELSE BEGIN
		IF (TEMPNT←GETOBJ(ARG,TRUE,CTEST))<0 THEN
			BEGIN STATUS ← -1;ARG ← NIL;RETURN END ELSE OBJLST ← TEMPNT;
		IF OLDARG≠NIL THEN OLDARG ← ARG;
		END;
	FOO ← PHI;
	SIMPLINES ← TRUE;
	IF ¬(CVN(ITVAR_II)) THEN ITVAR_II ← NIL;
	FOO ← GLOBAL EDGES⊗ITVAR_II;
	IF ¬(LENGTH(FOO)) THEN
		BEGIN
		SIMPLINES ← FALSE;
		FOO ← GLOBAL BOUNDARY⊗OLDARG;
		IF ¬LENGTH(FOO) THEN BEGIN STATUS←-2;ARG←NIL;RETURN;END;
		END;
	DO	BEGIN
		IF LENGTH(FOO)>1 THEN OUTSTR("DOUBLE STRUCTURE-COMPACT"&CRLF);
		OUTXY ← LOP(FOO);
		N ← DOUT(1,0);
		IF OLDARG≠NIL THEN FORG.;
		GULINK(OBJLST,CORPNT,FLAG);
		GULINK(OBJLST,OUTLIN,FLAG);
		FOR I←1 STEP 1 UNTIL N DO
			BEGIN
			X ← DOUT(1,I);
			Y ← DOUT(2,I);
			IF X<L THEN L←X;
			IF X>R THEN R←X;
			IF Y<T THEN T←Y;
			IF Y>B THEN B←Y;
			XX ← IF SIMPLINES THEN DOUT(3,I) ELSE DOUT(1,(I MOD N)+1);
			YY ← IF SIMPLINES THEN DOUT(4,I) ELSE DOUT(2,(I MOD N)+1);
			IF INTEST(X,Y,XX,YY) THEN
				BEGIN
				GET_BOX(X,Y,XX,YY);
				IF ¬BOXINC THEN BEGIN DEBOUT("""GET_BOX SCREWED UP"""); END;
				FOR J←1 STEP 1 UNTIL BOXINC DO SEENLINK(CVN(ARG),BOXTAB[J]);
				END;
			END;
		END UNTIL ¬LENGTH(FOO);
	GSETST(16,OBJLST,FLAG);
	DATPUT(OBJLST,LIMIT,4,T,B,L,R);
	STATUS ← IF SIMPLINES THEN 0 ELSE 1;
	IF ¬GIFTIE(OBJLST,CORRNG,FLAG) THEN GSETST(128,OBJLST,FLAG);
	IF OLDARG≠NIL∧YES_II THEN DISREL(OBJLST);
	END;
COMMENT		RELOOK COMMAND;

SIMPLE INTERNAL PROCEDURE LOOK(REFERENCE ITEMVAR ARG; REFERENCE INTEGER STATUS; INTEGER X, Y);
	BEGIN ITEMVAR Z;
	INTEGER TOP, BOT, LEFT, RIGHT, HOR, VER;
	REAL T,B,L,R;
	BOOLEAN SAVE;
	LABEL L2;
	STATUS ← 0;
	IF ARG=EVERY∨(PNTR←GETOBJ(ARG,FALSE,DUMMY))<0 THEN
		BEGIN STATUS ← -1;ARG ← NIL;RETURN;END;
	OBJLST ← PNTR;
	IF ¬(ARGεBLOBS) THEN GO TO L2;
	REMOVE ARG FROM BLOBS;
L2:	PUT ARG IN OLDBLOB;
	DATGET(OBJLST,LIMIT,4,T,B,L,R);
	TOP ← T; BOT ← B; LEFT ← L; RIGHT ← R;
	HOR ← (RIGHT-LEFT) DIV 2+15;
	VER ← (BOT-TOP) DIV 2+15;
	IF ¬X THEN X ← (RIGHT-LEFT) DIV 2+LEFT;
	IF ¬Y THEN Y ← (BOT-TOP) DIV 2+TOP;
	TOP ← Y-VER;
	BOT ← Y+VER;
	LEFT ← X-HOR;
	RIGHT ← X+HOR;
	IF TOP<TMAX THEN TOP ← TMAX;
	IF BOT>BMAX THEN BOT←BMAX;
	IF LEFT<LSMAX THEN LEFT ← LSMAX;
	IF RIGHT>RSMAX THEN RIGHT ← RSMAX;
	TOP ↔ TMAX;
	BOT ↔ BMAX;
	LEFT ↔ LSMAX;
	RIGHT ↔ RSMAX;
	XSTRT ← X;
	YSTRT ← BMAX-(BMAX-TMAX) DIV 4;
	REJSUB(Z←ARG, STATUS);
	SAVE ← SLIM;
	SLIM ← TRUE;
	EDGE_KKP(ARG,STATUS);
	SLIM ← SAVE;
	ARG ← NIL;
	STATUS ← 0;
	TOP ↔ TMAX;
	BOT ↔ BMAX;
	LEFT ↔ LSMAX;
	RIGHT ↔ RSMAX;
	END;
COMMENT		FILL DATA ARRAY FROM EDGE DATA RINGS;

SIMPLE PROCEDURE GET_DATA(SAFEX REAL ARRAY D; REFERENCE INTEGER CNT);
	BEGIN REAL X,Y;
	INTEGER PA,FA,TA,PB,FB,TB,CURCNT,LASTPNT;
	BOOLEAN CLOSED;
	CNT ← 0;
	GDOWN(PA ← OBJLST, FA ← OUTLIN, FLAG);
	TA ← PA LAND '777777;
	DO	BEGIN
		CURCNT ← 0;
		LASTPNT ← CNT ← CNT+1;
		CLOSED ← GSTATZ(7,PA,FLAG);
		GDOWN(PB ← PA, FB ← SEGPNT, FLAG);
		IF ¬CLOSED THEN WHILE GSTATZ(24,PB,FLAG) DO GBACK(PB,FB,FLAG);
		IF GSTATO(8,PB,FLAG)∧GSTATZ(16,PB,FLAG) THEN
			BEGIN
			DEBOUT("""FLAG MISSING - GET_DATA""");
			GFORWR(PB,FB,FLAG);
			GSETST(16,PB,FLAG);
			END;
		TB ← PB LAND '777777;
		DO	BEGIN
			CURCNT ← CURCNT+1;
			DATGET(PB,1,2,X,Y);
			D[CNT←CNT+1,1] ← X;
			D[CNT,2] ← Y;
			GFORWR(PB, FB, FLAG);
			END UNTIL TB=(PB LAND '777777);
		D[LASTPNT,1] ← IF CLOSED THEN CURCNT ELSE -CURCNT;
		D[LASTPNT,2] ← CNT+1;
		GFORWR(PA,FA,FLAG);
		END UNTIL TA=(PA LAND '777777);
	D[LASTPNT,2] ← 0;
	END;

COMMENT		DUMP DATA ARRAY ON DISK;

SIMPLE PROCEDURE DUMPDAT(SAFEX REAL ARRAY DAT; INTEGER K);
	BEGIN INTEGER LL,J;
	SETFORMAT(1,0);
	OPEN(DSK,"DSK",1,0,2,100,LL,LL);
	IF ¬RUN THEN BEGIN OUTSTR("SET NUMBER=");J←CVD(INCHWL);END ELSE J←RUN;
	ENTER(DSK,"DATA"&CVS(J MOD 100),FLAG);
	OUT(DSK,CVS(K)&CRLF);
	SETFORMAT(25,10);
	FOR J ← 1 STEP 1 UNTIL K DO OUT(DSK,CVF(DAT[J,1])&CVF(DAT[J,2])&CRLF);
	RELEASE(DSK);
	END;
COMMENT		INTERIOR EDGE SCANNER ROUTINES;

COMMENT		STATUS = -1	NO OBJECT
			0	NO FILE FOUND
			-N	FILE NUMBER (N>1);

INTEGER PROCEDURE ZSCAN;
	BEGIN SAFEX REAL ARRAY MAN[1:MANMAX+1,1:6];
	INTEGER EOF, SIXBIT1, FILN, SIXBIT2, BRK;
	STRING FOO;
	FILN ← -1;
	OPEN(DSK,"DSK",8,2,0,1000,BRK,EOF←0);
	LOOKUP(DSK,CVXSTR(CALL(0,"GETPPN"))&".UFD[1,1]",FLAG);
	IF FLAG THEN  RETURN(0);
	WHILE TRUE DO
		BEGIN
		SIXBIT1 ← WORDIN(DSK);
		IF EOF THEN DONE;
		SIXBIT2 ← WORDIN(DSK);
		IF SIXBIT1∧EQU(CVXSTR(SIXBIT2 LAND '777777000000)[1 FOR 3],"EDG") THEN
			FILN ← FILN MAX INTSCAN(FOO←CVXSTR(SIXBIT1),BRK);
		WORDIN(DSK); WORDIN(DSK);
		END;
	RELEASE(DSK);
	FILN ← ((FILN-2) DIV 3)*3+5;
	SETFORMAT(0,0);
	OPEN(DSK,"DSK",1,0,2,100,BRK,EOF←0);
	ENTER(DSK,CVS(FILN+1)&".EDG",FLAG);
	IF FLAG THEN RETURN(0);
	MANFRED ← GLOBAL NEW(MAN);
	MANFCNT ← 1;
	TMCNT ← 0;
	RETURN(FILN);
	END;

SIMPLE PROCEDURE OUTMAN;
	BEGIN DEFINE D="GLOBAL DATUM(MANFRED)";
	INTEGER N, J;
	J ← 1;
	MANFCNT ← MANFCNT-1;
	SETFORMAT(15,5);
	FOR N ← 1 STEP 1 UNTIL MANFCNT DO
		OUT(DSK,CVF(D[N,1])&CVF(D[N,2])&CVF(D[N,3])&CVF(D[N,4])&CRLF);
	TMCNT ← TMCNT+MANFCNT;
	MANFCNT ← 1;
	END;
COMMENT		ANOTHER INTERIOR EDGE SCANNING ROUTINE;

PROCEDURE EXSCAN(REFERENCE INTEGER STATUS, FILN);
	BEGIN INTEGER I;
	SAFEX REAL ARRAY TEMP[1:10,1:3];
	OUTMAN;
	IF STATUS≥0 THEN
		BEGIN
		CLOSE(DSK);
		SETFORMAT(0,0);
		ENTER(DSK,CVS(FILN)&".EDG",FLAG);
		IF FLAG THEN BEGIN FILN ← 0; RETURN; END;
		OUT(DSK,CVS(TMCNT)&CRLF&"0"&CRLF&CVS(SIDLEN+.5)&CRLF);
		OUT(DSK,(IF CVN(CURCAM) THEN "-1" ELSE "0")&CRLF);
		IF CVN(CURCAM) THEN ARRTRAN(TEMP,GLOBAL DATUM(CURCAM));
		SETFORMAT(20,8);
		FOR I←1 STEP 1 UNTIL 10 DO OUT(DSK,CVF(TEMP[I,1])&CVF(TEMP[I,2])&CVF(TEMP[I,3])&CRLF);
		STATUS ← -FILN;
		END ELSE BEGIN
		RENAME(DSK,NULL,0,FLAG);
		STATUS ← -1;
		FILN ← 0;
		END;
	GLOBAL DELETE(MANFRED);
	MANFRED ← NIL;
	RELEASE(DSK);
	END;
COMMENT		MORE INTERIOR EDGE SCANNING ROUTINES;

EXTERNAL BOOLEAN PROCEDURE OPSCAN(REFERENCE ITEMVAR ARG;REFERENCE INTEGER STATUS,EINIT;
	INTEGER T,B,L,R);

MESSAGE PROCEDURE INSCAN(INTEGER T, B, L, R;REFERENCE INTEGER FILN);
	BEGIN INTEGER STATUS;
	ITEMVAR ARG;
	BOOLEAN EINIT;
	FLAG ← STATUS ← 0;
	ARG ← NIL;
	FILN ← ZSCAN;
	IF FILN<2 THEN RETURN;
	T ↔ TMAX;
	B ↔ BMAX;
	L ↔ LSMAX;
	R ↔ RSMAX;
	EINIT ← TRUE;
	WHILE ¬OPSCAN(ARG,STATUS,EINIT,TMAX,BMAX,LSMAX,RSMAX) DO;
	T ↔ TMAX;
	B ↔ BMAX;
	L ↔ LSMAX;
	R ↔ RSMAX;
	EXSCAN(STATUS,FILN);
	END;

INTERNAL PROCEDURE INSUB(REFERENCE ITEMVAR ARG;REFERENCE INTEGER STATUS);
	BEGIN LABEL EOUT;
	BOOLEAN LIMT, SCN;
	INTEGER FILN;
	IF ARG=EVERY THEN
		BEGIN
		INSCAN(TMAX,BMAX,LSMAX,RSMAX,FILN);
		STATUS ← -FILN;
EOUT:		ARG ← NIL;
		RETURN;
		END;
	FILN ← ZSCAN;
	IF FILN<2 THEN BEGIN STATUS←0;GO TO EOUT;END;
	SCN ← SCAN_ACC;
	LIMT ← SLIM;
	SLIM ← TRUE;
	EDGE_KKP(ARG, STATUS);
	IF ARG=NIL∨STATUS<0 THEN STATUS ← -1;
	EXSCAN(STATUS,FILN);
	SCAN_ACC ← SCN;
	SLIM ← LIMT;
	ARG ← NIL
	END;
⊃  adaptive interior scanner - requires curve fitter running;

PROCEDURE ADAPT(SET BLOBS);
	BEGIN
	SAFEX REAL ARRAY CORNERS[1:100,1:2];
	LIST OBJS;
	INTEGER OBJCNT, OBJ, CORMAX, CORIND, I, J, K, M, CURSTAT, EINIT,
		BM, TM, LM, RM, PTR, DEBF, T, B, L, R;
	LABEL LOOP, NXTOBJ, NEWOBJ, FINISH,NXTXXX, JMPOUT;
	SET FOO;
	REAL TT, TB, TL, TR;
	REAL ARRAY ITEMVAR Z;
	ITEMVAR ARG, ARGX;
	BOOLEAN BIGSCAN;
	PRELOAD_WITH 2,0,3,1;
	SAFE OWN INTEGER ARRAY NEXTCOL[0:3];

	SIMPLE PROCEDURE COLOR(INTEGER CHG);
		BEGIN INTEGER I;
		CWHEEL(COLFILT_ACC←CHG);
		I←12000;
		WHILE I>0 DO I←I-1;
		END;

	SIMPLE PROCEDURE ADD(REAL X,Y);
		BEGIN INTEGER I;
		FOR I←CORMAX STEP -1 UNTIL 1 DO
			IF ABS(CORNERS[I,1]-X)<10.0∧ABS(CORNERS[I,2]-Y)<10.0 THEN RETURN;
		IF (CORMAX←CORMAX+1)>100 THEN USERERR(0,0,"CORMAX OVERFLOWED");
		CORNERS[CORMAX,1] ← X;
		CORNERS[CORMAX,2] ← Y;
		END;

	PROCEDURE SCN(INTEGER T,B,L,R);
		BEGIN INTEGER J;
		EINIT ← TRUE;
		WHILE ¬OPSCAN(ARGX←NIL, J, EINIT, T, B, L, R) DO
			BEGIN STRING INP;
			IF EQU(INP←INCHSL(J),"CANCEL") THEN GO TO JMPOUT;
			IF EQU(INP,"NEXT") THEN GO TO NXTOBJ;
			IF ARGX≠ARG∧¬LISTX(OBJS,ARGX,1) THEN
				PUT ARGX IN OBJS AFTER ∞;
			END;
		PTR ← GETOBJ(ARG,FALSE,DUMMY);
		END;

	IF COLFILT_ACC≠3 THEN COLOR(3);
	IF ST THEN BEGIN TM←TMAX; BM←BMAX; LM←LSMAX; RM←RSMAX; END ELSE
		BEGIN TM←15; BM←250; LM←10; RM←325; END;
	DEBF ← GETPOG;
	OBJS← CVLIST(BLOBS);
	OBJ ← 1;
NEWOBJ:	CORMAX ← CORIND ← 0;
	BIGSCAN ← FALSE;
	ARG ← OBJS[OBJ];
	PTR ← GETOBJ(ARG,FALSE,DUMMY);
	IF PTR≤0 THEN GO TO NXTOBJ;
LOOP:	GRSETS(8,PTR,J);
	CURVE(ARG,CURSTAT←-1);
	IF CURSTAT<0 THEN GO TO NXTOBJ;
	FOO ← GLOBAL BOUNDARY⊗ARG;
	IF LENGTH(FOO) THEN
		BEGIN
		Z ← LOP(FOO);
		J ← GLOBAL DATUM(Z)[1,0];
		FOR I←1 STEP 1 UNTIL J DO ADD(GLOBAL DATUM(Z)[1,I],GLOBAL DATUM(Z)[2,I]);
		END ELSE GRSETS(7,PTR,J);
	FOO ← GLOBAL INSIDE_EDGES⊗ARG;
	IF LENGTH(FOO) THEN
		BEGIN
		Z ← LOP(FOO);
		J ← GLOBAL DATUM(Z)[1,0];
		FOR I←1 STEP 1 UNTIL J DO
			BEGIN
			ADD(GLOBAL DATUM(Z)[1,I],GLOBAL DATUM(Z)[2,I]);
			ADD(GLOBAL DATUM(Z)[3,I],GLOBAL DATUM(Z)[4,I]);
			END;
		END;
	IF CORIND=CORMAX THEN GO TO FINISH;
	FOR I←CORIND+1 STEP 1 UNTIL CORMAX DO
		BEGIN "CORNER"
		INTEGER X,Y;
		X ← CORNERS[I,1]+.5;
		Y ← CORNERS[I,2]+.5;
		T ← (Y-15) MAX TM;
		B ← (Y+15) MIN BM;
		L ← (X-15) MAX LM;
		R ← (X+15) MIN RM;
		IF DEBUGX THEN
			BEGIN INTEGER DSAVE;
			SAFEX INTEGER ARRAY DISPLD[1:50];
			DSAVE ← DPYPARS;
			DPYSET(DISPLD);
			FADCHG(L,T,AIVECT);
			FRDCHG(R,T,RVECT);
			FRDCHG(R,B,RVECT);
			FRDCHG(L,B,RVECT);
			FRDCHG(L,T,RVECT);
			DPYOUT(DEBF);
			DPYRESET(DSAVE);
			END;
		SCN(T,B,L,R);
		END "CORNER";
	CORIND ← CORMAX;
	IF GSTATZ(8,PTR,J) THEN GO TO LOOP;
FINISH:	IF BIGSCAN THEN GO TO NXTXXX;
	DATGET(PTR,LIMIT,4,TT,TB,TL,TR);
	T ← TM MAX (TT-15);
	B ← BM MIN (TB-15);
	L ← LM MAX (TL-15);
	R ← RM MIN (TR+15);
	I ← CIRCLE;
	K ← ((B-T-2*I) DIV 30) MAX 6;
	M ← (B-T-2*I) DIV K;
	IF M>4 THEN
		BEGIN
		IF DEBUGX THEN
			BEGIN INTEGER DSAVE;
			SAFEX INTEGER ARRAY DISPLD[1:50];
			DSAVE ← DPYPARS;
			DPYSET(DISPLD);
			FADCHG(L,T,AIVECT);
			FRDCHG(R,T,RVECT);
			FRDCHG(R,B,RVECT);
			FRDCHG(L,B,RVECT);
			FRDCHG(L,T,RVECT);
			DPYOUT(DEBF);
			DPYRESET(DSAVE);
			END;
		FOR J←B-I STEP -M UNTIL T+I DO SCN(J-I,J+I,L,R);
		END;
	T←TT; B←TB; L←TL; R←TR;
	DATGET(PTR,LIMIT,4,TT,TB,TL,TR);
	IF TT≥T∧TB≤B∧TL≥L∧TR≤R THEN BIGSCAN ← TRUE;
	IF GSTATZ(8,PTR,J) THEN GO TO LOOP;
NXTXXX:	GSETST(32,PTR,J);
NXTOBJ:	GRSETS(8,PTR,J);
	IF (OBJ←OBJ+1)≤LENGTH(OBJS) THEN GO TO NEWOBJ;
	IF ¬ST∧DO_COL THEN
		BEGIN "FILCHG"
		OBJ←1;
		COLOR(NEXTCOL[COLFILT_ACC]);
		IF FIL_ACC[COLFILT_ACC] THEN AUTO_ACC←FIL_ACC[COLFILT_ACC] ELSE
			BEGIN CHANGE_ACC←TRUE;SCANINIT;FIL_ACC[COLFILT_ACC]←AUTO_ACC;END;
		IF COLFILT_ACC≠3 THEN GO TO NEWOBJ;
		END "FILCHG";
JMPOUT:	RELPOG(DEBF);
	END;
COMMENT		NON-ADAPTIVE INTERIOR EDGE SCANNER - CURVE FITTER NOT NEEDED;

INTERNAL PROCEDURE FINSCN(SET BLOBS; INTEGER FILN; REFERENCE INTEGER STATUS);
	BEGIN LABEL L1, LOOP, INOUT, L3, L2,L4,L5;
	SAFEX ITEMVAR ARRAY OBJS[1:30];
	SAFEX INTEGER ARRAY LIM[1:30,0:4];
	INTEGER OCNT,I,INCR,TS,LS,BS,RS,OBJ,SIZ,AREA,J,K,A,T,B,R,L,HT,HB,HR,HL,TVW,
		LT, LB, LR, LL, XT, XB, XR, XL,TA,BA,LA,RA,EOF,BRK,STT,SB,SR,SL,DEBF,XSAVE,YSAVE;
	BOOLEAN EINIT,FLAG,LIMT,SCN,NEWBUF;
	SAFEX REAL ARRAY MAN[1:MANMAX+1,1:6];
	ITEMVAR ARG;

	SIMPLE BOOLEAN PROCEDURE LIMS(INTEGER I);
		BEGIN INTEGER PTR;
		REAL TTA,TBA,TLA,TRA;
		PTR ← GETOBJ(OBJS[I],FALSE,DUMMY);
		IF PTR>0 THEN
			BEGIN
			DATGET(PTR,LIMIT,4,TTA,TBA,TLA,TRA);
			TA←TTA;BA←TBA;LA←TLA;RA←TRA;
			END ELSE BEGIN
			OBJS[I] ← NIL;
			IF I=OCNT THEN OCNT ← OCNT-1;
			END;
		RETURN(PTR>0);
		END;

	XSAVE ← XSTRT;
	YSAVE ← YSTRT;
	CLIPCHG(0);
	SCN ← SCAN_ACC;
	LIMT ← SLIM;
	TVW ← TVWORD;
	SLIM ← TRUE;
	IF DEBUGX THEN DEBF ← GETPOG;
	IF FILN THEN
		BEGIN
		SETFORMAT(0,0);
		OPEN(DSK,"DSK",1,2,2,100,BRK,EOF ←0);
		ENTER(DSK,CVS(FILN+2)&".EDG",FLAG);
		MANFRED ← GLOBAL NEW(MAN);
		MANFCNT ← 1;
		END;
	TMCNT ← 0;
	TS←TMAX;BS←BMAX;RS←RSMAX;LS←LSMAX;
	IF YES_CUR THEN BEGIN ADAPT(BLOBS); GO TO INOUT; END;
	XT ← LT ← IF ST THEN TMAX ELSE 15;
	XB ← LB ← IF ST THEN BMAX ELSE 250;
	XR ← LR ← IF ST THEN RSMAX ELSE 325;
	XL ← LL ← IF ST THEN LSMAX ELSE 10;
COMMENT		CONTINUE;

	NEWBUF← SCAN_ACC ← FALSE;
	INCR←CIRCLE;
	SIZ ← SIZE;
L2:	IF FLAG∨¬LENGTH(BLOBS) THEN BEGIN STATUS←0; RETURN; END;
	OBJS[OBJ←OCNT←1] ← LOP(BLOBS);
	LIM[OBJ,0] ← TRUE;
	IF ¬LIMS(OBJ) THEN GO TO L2;
	FLINE←TMAX←(TA-10) MAX LT;
	LLINE←BMAX←(BA+10) MIN LB;
	RSIDE←RSMAX←(RA+10) MIN LR;
	LSIDE←LSMAX←(LA-10) MAX LL;
	WHILE LENGTH(BLOBS) DO
		BEGIN
		OBJS[OCNT ← OCNT+1] ← LOP(BLOBS);
		IF LIMS(OCNT)∧(TA<TMAX∨BA>BMAX∨RA>RSMAX∨LA<LSMAX) THEN
			BEGIN
			LIM[OCNT,0] ← TRUE;
			LIM[OCNT,1] ← (TA-10) MAX LT;
			LIM[OCNT,2] ← (BA+10) MIN LB;
			LIM[OCNT,3] ← (RA+10) MIN LR;
			LIM[OCNT,4] ← (LA-10) MAX LL;
			END;
		END;
L1:	I←((RSMAX-LSMAX+1)/9+2)*(BMAX-TMAX+1);
	IF ¬ST∧I>SIZ THEN
		BEGIN
		IF NEWBUF THEN RELCOR(TVWORD);
		NEWBUF←SIZ←I;
		TVWORD ← GETCOR(SIZ);
		END;
	IF ¬ST THEN BEGIN TVIN; EJINIT;END;
	IF DEBUGX THEN
		BEGIN INTEGER DSAVE;
		SAFEX INTEGER ARRAY DISPLD[1:50];
		DSAVE ← DPYPARS;
		DPYSET(DISPLD);
		FADCHG(LSIDE,FLINE,AIVECT);
		FRDCHG(LSIDE,LLINE,RVECT);
		FRDCHG(RSIDE,LLINE,RVECT);
		FRDCHG(RSIDE,FLINE,RVECT);
		FRDCHG(LSIDE,FLINE,RVECT);
		DPYOUT(DEBF);
		DPYRESET(DSAVE);
		END;
COMMENT		CONTINUE;

LOOP:	EINIT ← TRUE;
	IF ST THEN BEGIN XT↔FLINE;XB↔LLINE;XR↔RSIDE;XL↔LSIDE;STT←XT;SB←XB;SR←XR;SL←XL;END ELSE
		BEGIN STT←FLINE;SB←LLINE;SR←RSIDE;SL←LSIDE;END;
	WHILE ¬OPSCAN(ARG←NIL,STATUS,EINIT,STT,SB,SL,SR) DO
		BEGIN
		IF ST THEN BEGIN XT↔FLINE;XB↔LLINE;XR↔RSIDE;XL↔LSIDE;END;
		OBJS[OCNT+1]←ARG;
		IF LIMS(OCNT+1)∧(TA<TMAX∨BA>BMAX∨RA>RSMAX∨LA<LSMAX) THEN
			BEGIN
			IF ARG≠OBJS[OBJ] THEN
				BEGIN
				FOR I←1 STEP 1 UNTIL OCNT DO IF I≠OBJ∧ARG=OBJS[I] THEN DONE;
				IF I>OCNT THEN
					BEGIN
					FOR I←1 STEP 1 UNTIL OCNT DO IF OBJS[I]=NIL THEN DONE;
					IF I>OCNT THEN OCNT ← I;
					OBJS[I] ← ARG;
					END;
				LIM[I,0] ← TRUE;
				LIM[I,1] ← (TA-10) MAX LT;
				LIM[I,2] ← (BA+10) MIN LB;
				LIM[I,3] ← (RA+10) MIN LR;
				LIM[I,4] ← (LA-10) MAX LL;
				END;
			IF ¬ST THEN
				BEGIN
				FLINE ← STT; LLINE←SB; RSIDE←SR; LSIDE←SL;
				TVIN; EJINIT;
				END;
			END;
		IF ST THEN BEGIN XT↔FLINE;XB↔LLINE;XR↔RSIDE;XL↔LSIDE;END;
		END;
	IF ST THEN BEGIN XT↔FLINE;XB↔LLINE;XR↔RSIDE;XL↔LSIDE;END;
L5:	IF LIMS(OBJ) THEN
		BEGIN
		T ← TMAX MIN TA;
		B ← BMAX MAX BA;
		R ← RSMAX MAX RA;
		L ← LSMAX MIN LA;
		IF T<TMAX∨B>BMAX∨R>RSMAX∨L<LSMAX THEN
			BEGIN
			FLINE←TMAX; LLINE←BMAX; RSIDE←RSMAX; LSIDE←LSMAX;
			IF T<TMAX THEN BEGIN LLINE←TMAX+10;FLINE←TMAX←(T-10) MAX LT; END ELSE
			IF B>BMAX THEN BEGIN FLINE←BMAX-10;LLINE←BMAX←(B+10) MIN LB; END ELSE
			IF L<LSMAX THEN BEGIN RSIDE←LSMAX+10;LSIDE←LSMAX←(L-10) MAX LL; END ELSE
			IF R>RSMAX THEN BEGIN LSIDE←RSMAX-10;RSIDE←RSMAX←(R+10) MIN LR; END;
			GO TO L1;
			END;
		END;
COMMENT		CONTINUE;

	LIM[OBJ,1] ← TMAX;
	LIM[OBJ,2] ← BMAX;
	LIM[OBJ,3] ← RSMAX;
	LIM[OBJ,4] ← LSMAX;
	LIM[OBJ,0] ← FALSE;
	IF (J ← GETOBJ(OBJS[OBJ],FALSE,DUMMY))>0 THEN GSETST(32,J,FLAG);
L3:	FOR OBJ←1 STEP 1 UNTIL OCNT DO IF OBJS[OBJ]≠NIL∧LIM[OBJ,0] THEN DONE;
	IF OBJ>OCNT THEN
INOUT:		BEGIN
		OUTOBJ(STATUS);
		IF FILN THEN
			BEGIN
			OUTMAN;
			IF TMCNT>0 THEN
				BEGIN SAFEX STRING ARRAY LINES[1:12];
				SETBREAK(10,'12,'15,"I");
				CLOSE(DSK);
				SETFORMAT(0,0);
				LOOKUP(DSK,CVS(FILN)&".EDG",FLAG);
				IF FLAG THEN FILN←0 ELSE
					BEGIN
					FOR I←1 STEP 1 UNTIL 12 DO LINES[I]←INPUT(DSK,10);
					LINES[2] ← CVS(TMCNT);
					CLOSE(DSK);
					ENTER(DSK,CVS(FILN)&".EDG",FLAG);
					IF FLAG THEN FILN←0 ELSE
						FOR I←1 STEP 1 UNTIL 12 DO OUT(DSK,LINES[I]&CRLF);
					END;
				END ELSE FILN←1;
			RELEASE(DSK);
			GLOBAL DELETE(MANFRED);
			END;
		MANFRED ← NIL;
		IF NEWBUF THEN BEGIN RELCOR(TVWORD);TVWORD←TVW;END;
		SCAN_ACC ← SCN;
		SLIM ← LIMT;
		TMAX←TS;BMAX←BS;RSMAX←RS;LSMAX←LS;
		IF ST THEN BEGIN FLINE←TS; LLINE←BS; RSIDE ← RS; LSIDE ←LS;END;
		STATUS ← -FILN;
		IF DEBUGX THEN RELPOG(DEBF);
		CLIPCHG(1);
		XSTRT ← XSAVE;
		YSTRT ← YSAVE;
		RETURN;
		END;
COMMENT		CONTINUE;

	FLINE ← TMAX ← T ← LIM[OBJ,1];
	LLINE ← BMAX ← B ← LIM[OBJ,2];
	RSIDE ← RSMAX ← R ← LIM[OBJ,3];
	LSIDE ← LSMAX ← L ← LIM[OBJ,4];
	A ← (B-T)*(R-L);
	J ← AREA ← -1;
	FOR I←1 STEP 1 UNTIL OCNT DO IF I≠OBJ THEN
		BEGIN
		IF ¬LIMS(I) THEN GO TO L4;
		TA←LIM[I,1];BA←LIM[I,2];RA←LIM[I,3];LA←LIM[I,4];
		HT ← IF TA≤T THEN T ELSE IF TA≥B THEN B ELSE TA;
		HB ← IF BA≥B THEN B ELSE IF BA≤T THEN T ELSE BA;
		HL ← IF LA≤L THEN L ELSE IF LA≥R THEN R ELSE LA;
		HR ← IF RA≥R THEN R ELSE IF RA≤L THEN L ELSE RA;
		K ← (HR-HL)*(HB-HT);
		IF ¬K THEN GO TO L4;
		IF K=A THEN BEGIN OBJS[OBJ] ← NIL; GO TO L3; END;
		IF K>AREA THEN BEGIN AREA←K; J ← I; END;
L4:		END;
		IF J>0 THEN
			BEGIN
		TA←LIM[J,1];BA←LIM[J,2];RA←LIM[J,3];LA←LIM[J,4];
			TMAX ← IF TA≤T THEN T ELSE IF TA≥B THEN B ELSE TA;
			BMAX ← IF BA≥B THEN B ELSE IF BA≤T THEN T ELSE BA;
			LSMAX ← IF LA≤L THEN L ELSE IF LA≥R THEN R ELSE LA;
			RSMAX ← IF RA≥R THEN R ELSE IF RA≤L THEN L ELSE RA;
			GO TO L5;
			END;
	GO TO L1;
	END;

COMMENT		CALLING PROGRAM FOR FINE OPERATION;

INTERNAL PROCEDURE XFINE(REFERENCE ITEMVAR ARG; REFERENCE INTEGER STATUS);
	BEGIN ITEMVAR NARG;

	SIMPLE BOOLEAN PROCEDURE TST(REFERENCE INTEGER P;REFERENCE ITEMVAR ARG);
		RETURN(GSTATZ(32,P,FLAG));

	IF (PNTR←GETOBJ(ARG,TRUE,TST))<0 THEN
		BEGIN
		STATUS ← -1;
		ARG ← NIL;
		RETURN;
		END;
	NARG ← IF ARG=EVERY THEN CVI(GGETD(PNTR,OBJNUM,FLAG)) ELSE ARG;
	OBJLST ← PNTR;
	FINSCN({NARG},0,STATUS);
	STATUS ← 0;
	END;
COMMENT		GUTS OF GET_DATA COMMAND;

INTERNAL BOOLEAN PROCEDURE XGETD(ITEMVAR ARG; STRING JOB);
	BEGIN
	INTEGER SIZ, PNTR, K;
	IF ARG=EVERY∨(PNTR←GETOBJ(ARG,FALSE,DUMMY))<0 THEN RETURN(TRUE);
	SIZ ← GGETD(PNTR, PNTNUM, FLAG)+GCOUNT(PNTR,OUTLIN,FLAG);
	IF FLAG∨¬SIZ THEN RETURN(TRUE);
		BEGIN
		SAFEX REAL ARRAY DAT[1:(SIZ+20),1:2];
		OBJLST ← PNTR;
		GET_DATA(DAT,K);
		IF EQU(JOB,"TTY") THEN DUMPDAT(DAT,K) ELSE
			ISSUE(1,"EDGE",JOB,MESSAGE SEND_DATA(K, DAT));
		RETURN(FALSE);
		END;
	END;

COMMENT		DUMP GLOBAL DATA FOR SIMPLE;

INTERNAL PROCEDURE GDUMP;
	BEGIN INTEGER BREAK, EOF, J;
	SAFEX REAL ARRAY ITEMVAR X, Y;
	SET FOO, TEMP;
	DEFINE XFER(A,B)="ARRYOUT(2,A,B)";
	Y ← COP(BLOBS);
	TEMP ← GLOBAL XFORM⊗Y;
	IF ¬LENGTH(TEMP) THEN  RETURN;
	SETFORMAT(0,0);
	OPEN(2,"DSK",'10,0,2,200,BREAK,EOF);
	OUTSTR("SCENE NUMBER="&CRLF);
	ENTER(2,"EDG"&INCHWL&".SCN",EOF);
	Y ← COP(TEMP);
	XFER("GLOBAL DATUM(Y)[1,1]",30);
	FOO ← BLOBS;
	J ← LENGTH(FOO);
	XFER(J,1);
	WHILE LENGTH(FOO) DO
		BEGIN
		X ← LOP(FOO);
		TEMP ← GLOBAL BOUNDARY⊗X;
		IF LENGTH(TEMP) THEN
			BEGIN
			Y ← LOP(TEMP);
			J ← GLOBAL DATUM(Y)[1,0];
			XFER(J,1);
			XFER("GLOBAL DATUM(Y)[1,0]",(J+1)*2);
			END ELSE XFER(0,1);
		TEMP ← GLOBAL INSIDE_EDGES⊗X;
		IF LENGTH(TEMP) THEN
			BEGIN
			Y ← LOP(TEMP);
			J ← GLOBAL DATUM(Y)[1,0];
			XFER(J,1);
			XFER("GLOBAL DATUM(Y)[1,0]",(J+1)*4);
			END ELSE XFER(0,1);
		END;
	RELEASE(2);
	END;
COMMENT		FIT COMMAND  STATUS=-1 ON ENTRY IF NO LINE EXTENDING TO BE DONE
	STATUS=	-2	CURVE FITTER BLEW UP (INTERNAL ONLY)
		-1	NO OBJECT
		0	OK
		1	OK BUT NOT A CLOSED CURVE;

INTERNAL PROCEDURE CURVE(REFERENCE ITEMVAR ARG; REFERENCE INTEGER STATUS);
	BEGIN INTEGER I, J, SIZ;
	LABEL L1, L2;
	REAL X, Y, XX, YY;

	SIMPLE BOOLEAN PROCEDURE TEST(REFERENCE INTEGER PNTR;REFERENCE ITEMVAR ARG);
		RETURN(GSTATZ(8,PNTR,FLAG));
	TRACCHK;
	IF (PNTR←GETOBJ(ARG,TRUE,TEST))<0 THEN
		BEGIN
L1:		STATUS ← -1;
		ARG ← NIL;
		RETURN;
		END;
	DEL("BOUNDARY⊗ARG");
	DEL("INSIDE_EDGES⊗ARG");
	GLOBAL ERASE XFORM⊗ARG≡ANY;
	OBJLST ← PNTR;
	CURVE_STATUS ← STATUS=-1;
	SIZ ← GGETD(PNTR,PNTNUM,FLAG)+GCOUNT(PNTR,OUTLIN,FLAG)+20;
	IF SIZ<21 THEN GO TO L1;
		BEGIN SAFEX REAL ARRAY DAT[1:SIZ,1:2];
		GET_DATA(DAT,SIZ);
		ITVAR_II ← ARG;
		IF SIZ<2 THEN GO TO L1;
		IF YES_CUR THEN I←ISSUE(0,"EDGE","CURVE",MESSAGE CURVE_FIT(DAT))
			ELSE DUMPDAT(DAT,SIZ);
		END;
	IF YES_CUR THEN QUEUE(7,I);
	STATUS ← CURVE_STATUS;
	IF STATUS=-2 THEN
		BEGIN
		REJSUB(ARG,I);
		DEL(ANY⊗ARG);
		STATUS ← -1;
		RETURN;
		END;
	NEWCAM ← CVI(GGETD(OBJLST,CAMERA,FLAG));
	IF NEWCAM≠NIL THEN GLOBAL MAKE XFORM⊗ARG≡NEWCAM;
	GSETST(8,OBJLST,FLAG);
	IF YES_CUR THEN REGEN(OBJLST);
L2:	CORLST ← CURTEM ← TEMPNT ← PNTLST ← SEGLST ← -1;
	END;
END "MISC";